// $Id: PetriNetElementAnchor.cs 126 2007-05-28 19:01:12Z xavex2k $

using System;
using System.Drawing;
using Diagram;
using Diagram.Handles;

namespace PetriDiagram.Shapes
{
    [Serializable]
    public class PetriNetElementAnchor : Anchor
    {
        private TransitionShape transition;

        public PetriNetElementAnchor( TransitionShape element )
            : base( element )
        {
            transition = element;
        }

        public override void OnDrag( Movement movement )
        {
            MoveToCenter();
            base.OnDrag( new Movement( Location, Size.Empty ) );
        }

        private void MoveToCenter()
        {
            Point pt = GetSecondHandle().Location;

            Point left = new Point( transition.Bounds.Left, transition.Middle.Y );
            Point right = new Point( transition.Bounds.Right, transition.Middle.Y );
            Point top = new Point( transition.Middle.X, transition.Bounds.Top );
            Point bottom = new Point( transition.Middle.X, transition.Bounds.Bottom );

            double distLeft = Distance( left, pt );
            double distRight = Distance( right, pt );
            double distTop = Distance( top, pt );
            double distBottom = Distance( bottom, pt );

            Point p = left;

            if( distRight <= distLeft )
                p = right;

            if( distTop <= distRight && distTop <= distLeft )
                p = top;

            if( distBottom <= distTop && distBottom <= distRight && distBottom <= distLeft )
                p = bottom;

            Location = p;
        }

        public override void OnDragDrop( Movement movement )
        {
            MoveToCenter();
            base.OnDragDrop( new Movement( Location, Size.Empty ) );
        }

        public override void UpdatePosition()
        {
            base.UpdatePosition();

            OnDragDrop( new Movement( Location, Size.Empty ) );

        }

        private Handle GetSecondHandle()
        {
            if( !IsStartingAnchor )
                return ParentConnection.Handles[ ParentConnection.Handles.Count - 2 ];
            else
                return ParentConnection.Handles[ 1 ];
        }

        private double Distance( Point p1, Point p2 )
        {
            return Math.Sqrt( Math.Pow( p1.X - p2.X, 2 ) + Math.Pow( p1.Y - p2.Y, 2 ) );
        }
    }
}
